package org.unidata.mdm.dq.core.type.model.source;

import java.io.Serializable;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import javax.xml.datatype.XMLGregorianCalendar;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

/**
 * A group of cleanse functions and sub groups..
 */
public class CleanseFunctionGroup implements Serializable {
    /**
     * GSVUID.
     */
    private static final long serialVersionUID = 3369198218468532377L;

    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "group")
    private List<CleanseFunctionGroup> groups;

    @JacksonXmlProperty(isAttribute = true)
    private String name;

    @JacksonXmlProperty(isAttribute = true)
    private String displayName;

    @JacksonXmlProperty(isAttribute = true)
    private String description;

    @JacksonXmlProperty(isAttribute = true)
    private OffsetDateTime updateDate;

    @JacksonXmlProperty(isAttribute = true)
    private OffsetDateTime createDate;

    @JacksonXmlProperty(isAttribute = true)
    private String updatedBy;

    @JacksonXmlProperty(isAttribute = true)
    private String createdBy;

    private List<String> mappedFunctions;

    /**
     * Returns a list of groups.
     */
    public List<CleanseFunctionGroup> getGroups() {
        if (groups == null) {
            groups = new ArrayList<>();
        }
        return groups;
    }

    /**
     * @param groups the groups to set
     */
    public void setGroups(List<CleanseFunctionGroup> groups) {
        this.groups = groups;
    }

    /**
     * @return the mappedRegisters
     */
    public List<String> getMappedFunctions() {
        if (mappedFunctions == null) {
            mappedFunctions = new ArrayList<>();
        }
        return mappedFunctions;
    }

    /**
     * Gets the value of the groupName property.
     *
     * @return possible object is
     * {@link String }
     */
    public String getName() {
        return name;
    }

    /**
     * Sets the value of the groupName property.
     *
     * @param value allowed object is
     * {@link String }
     */
    public void setName(String value) {
        this.name = value;
    }

    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(String value) {
        this.displayName = value;
    }

    /**
     * Gets the value of the description property.
     *
     * @return possible object is
     * {@link String }
     */
    public String getDescription() {
        return description;
    }

    /**
     * Sets the value of the description property.
     *
     * @param value allowed object is
     * {@link String }
     */
    public void setDescription(String value) {
        this.description = value;
    }

    /**
     * Gets the value of the updatedAt property.
     *
     * @return
     *     possible object is
     *     {@link XMLGregorianCalendar }
     *
     */
    public OffsetDateTime getUpdateDate() {
        return updateDate;
    }

    /**
     * Sets the value of the updatedAt property.
     *
     * @param value
     *     allowed object is
     *     {@link XMLGregorianCalendar }
     *
     */
    public void setUpdateDate(OffsetDateTime value) {
        this.updateDate = value;
    }

    /**
     * Gets the value of the createdAt property.
     *
     * @return
     *     possible object is
     *     {@link XMLGregorianCalendar }
     *
     */
    public OffsetDateTime getCreateDate() {
        return createDate;
    }

    /**
     * Sets the value of the createdAt property.
     *
     * @param value
     *     allowed object is
     *     {@link XMLGregorianCalendar }
     *
     */
    public void setCreateDate(OffsetDateTime value) {
        this.createDate = value;
    }

    /**
     * Gets the value of the updatedBy property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getUpdatedBy() {
        return updatedBy;
    }

    /**
     * Sets the value of the updatedBy property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setUpdatedBy(String value) {
        this.updatedBy = value;
    }

    /**
     * Gets the value of the createdBy property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getCreatedBy() {
        return createdBy;
    }

    /**
     * Sets the value of the createdBy property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setCreatedBy(String value) {
        this.createdBy = value;
    }

    public CleanseFunctionGroup withName(String value) {
        setName(value);
        return this;
    }

    public CleanseFunctionGroup withDisplayName(String value) {
        setDisplayName(value);
        return this;
    }

    public CleanseFunctionGroup withDescription(String value) {
        setDescription(value);
        return this;
    }

    public CleanseFunctionGroup withCreateDate(OffsetDateTime value) {
        setCreateDate(value);
        return this;
    }

    public CleanseFunctionGroup withCreatedBy(String value) {
        setCreatedBy(value);
        return this;
    }

    public CleanseFunctionGroup withUpdateDate(OffsetDateTime value) {
        setUpdateDate(value);
        return this;
    }

    public CleanseFunctionGroup withUpdatedBy(String value) {
        setUpdatedBy(value);
        return this;
    }

    public CleanseFunctionGroup withGroups(CleanseFunctionGroup... values) {
        if (ArrayUtils.isNotEmpty(values)) {
            return withGroups(Arrays.asList(values));
        }
        return this;
    }

    public CleanseFunctionGroup withGroups(Collection<CleanseFunctionGroup> values) {
        if (CollectionUtils.isNotEmpty(values)) {
            getGroups().addAll(values);
        }
        return this;
    }

    public CleanseFunctionGroup withMappedFunctions(String... values) {
        if (ArrayUtils.isNotEmpty(values)) {
            return withMappedFunctions(Arrays.asList(values));
        }
        return this;
    }

    public CleanseFunctionGroup withMappedFunctions(Collection<String> values) {
        if (CollectionUtils.isNotEmpty(values)) {
            getMappedFunctions().addAll(values);
        }
        return this;
    }
}
